home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
wasm201.arc
/
SPLIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-12-28
|
12KB
|
400 lines
Title 'Wolfware Assembler Sample', 'Page Splitter'
;===============================================;
; Page Splitter Version 1.00 ;
; ;
; This program splits a text file into two new ;
; files, one containing all the even pages, and ;
; the other containing all the odd pages. Pages ;
; are determined by formfeeds (ASCII 12). ;
; Splitting up a file like this allows one to ;
; print all the right hand pages, then feed the ;
; same pages back into the printer (upside ;
; down) to print all the left hand pages, ;
; resulting in double sided printing. This ;
; saves much paper and makes things like ;
; a printed documentation look better. ;
; ;
; Once assembled, just type SPLIT and answer ;
; the questions. ;
; ;
; The some of the macros defined in DOS.MAC and ;
; MISC.MAC are required, thus those two files ;
; are are expected on the default drive. ;
;===============================================;
Jmp Begin
Include 'Dos.Mac' ;insert DOS routines
Include 'Misc.Mac' ;insert miscellaneous routines
;----- equates
Name_Size Equ 30 ;maximum size of file names
Read_Size Equ 20000 ;size of read buffer
Write_Size Equ 10000 ;size of write buffer
Formfeed Equ 12 ;start of new page character
Stack_Size Equ 100h ;size of stack
;----- status
Even Equ 00000001b ;even page bit
First Equ 00000010b ;first even page bit
Status Db First ;status
;----- file information
Src_Handle Dw ? ;source handle
Src_Point Dw 0 ;data pointer
Src_End Dw 0 ;end of data pointer
Src_Seg Dw ? ;data segment
Odd_Handle Dw ? ;odd pages handle
Odd_Point Dw 0 ;data pointer
Odd_Seg Dw ? ;data segment
Eve_Handle Dw ? ;even pages handle
Eve_Point Dw 0 ;data pointer
Eve_Seg Dw ? ;data segment
;----- opening message
Open_Mess Db Offset Mess2 - Offset Mess1
Mess1
Db 13,10
Db 'File Splitter Version 1.00',13,10
Db 13,10
Db 'Extracts the odd and even pages out',13,10
Db 'of a standard text file and puts them',13,10
Db 'into their own separate files.',13,10
Db 13,10
Mess2
;===============================================;
; Main Program ;
;===============================================;
Begin
Trap_Break User_Break ;trap user break
Display_String Offset Open_Mess ;opening display
;----- reduce present code segment
Mov Bx, $Size + 100h / 16 +1 ;new size
Dos_Function 4ah ;change allocation
;----- switch to new stack
Allocate Stack_Size ;allocate stack segment
Jc BadMem ;jump if error
Cli ;int's off
Mov Ss, Ax ;segment
Mov Sp, Stack_Size ;pointer
Sti ;int's back on
;----- allocate data segments
Allocate Read_Size, Src_Seg ;allocate source segment
Jc BadMem ;jump if error
Allocate Write_Size, Odd_Seg ;allocate odd write segment
Jc BadMem ;jump if error
Allocate Write_Size, Eve_Seg ;allocate evem write segment
Jc BadMem ;jump if error
Jmps Filestar
;----- memory error
BadMem
Bell ;sound speaker
Display_Line 'Insufficient memory' ;message
Exit 2 ;exit with error code 2
;----- get files and open
Filestar
Display_String 'File to split: ' ;prompt
Call Input_Name ;input file name
Open Dx, Src_Handle ;open file, save file handle
Jc BadFile ;jump if could not open
Display_String 'File to receive odd pages: ' ;prompt
Call Input_Name ;input file name
Call Create_File ;create file
Mov Odd_Handle, Ax ;save handle
Jc BadFile ;jump if could not open
Display_String 'File to receive even pages: ' ;prompt
Call Input_Name ;input file name
Call Create_File ;create file
Mov Eve_Handle, Ax ;save handle
Jc BadFile ;jump if could not open
Jmps Srcloop ;jump if ok
;----- file error
BadFile
Bell ;sound speaker
Display_Line 'Error in file' ;message
Exit 1 ;exit with error code 1
;----- process file
;----- read next byte
Srcloop
Mov Bx, Src_Handle ;handle
Mov Cx, Read_Size ;buffer size
Mov Dx, Src_Seg ;segment
Mov Si, Src_Point ;pointer
Mov Di, Src_End ;end pointer
Call Get_Byte ;get next byte
Jc Done ;jump if done
Mov Src_Point, Si ;save pointer
Mov Src_End, Di ;save end pointer
;----- look for formfeed, the formfeed on
;----- the first even page is dropped
Cmp Al, Formfeed ;check if new page
Jne Noreverse ;jump if not
Xor Status, Even ;flip page type
Test Status, First ;check if first even page
Jz Noreverse ;jump if not
Test Status, Even ;check if really even page
Jz Noreverse ;jump if not
And Status, Not First ;clear first even page bit
Jmp Srcloop ;loop back for next byte, skip FF
;----- save byte to odd or even file
Noreverse
Call Divide_Byte ;write byte to respective file
Jc Diskfull ;jump if write error
Jmp Srcloop ;loop back for next byte
;----- disk full error
Diskfull
Bell ;sound speaker
Display_Line 'Disk full' ;message
Exit 1 ;exit with error code 1
;----- finished
Done
Close Src_Handle ;close source file
Mov Bx, Odd_Handle ;handle
Mov Cx, Odd_Point ;bytes in buffer
Mov Dx, Odd_Seg ;segment
Call Write_Bytes ;write final bytes
Close Bx ;close
Mov Bx, Eve_Handle ;handle
Mov Cx, Eve_Point ;bytes in buffer
Mov Dx, Eve_Seg ;segment
Call Write_Bytes ;write final bytes
Close Bx ;close
Display_Line 'Finished' ;final message
Exit ;exit
;===============================================;
; Allocate ;
; Macro to allocate the specified number of ;
; bytes and save the segment. ;
;===============================================;
Allocate Macro Bytes, Segment
Mov Bx, Bytes / 16 +1 ;number of paragraphs to allocate
Dos_Function 48h ;execute
If_Exist Segment
Mov Segment, Ax ;save segment
Endif
Endm
;===============================================;
; Input_Name ;
; Input a file name. DX returns the offset of ;
; the name. ;
;===============================================;
Input_Name Proc Near
Input_String Dx, Name_Size ;input name
Inc Dx ;skip length byte
Ret
Endp
;===============================================;
; Create_File ;
; Create (or truncate) the file whose name is ;
; at DX. AX returns the file handle, or the ;
; carry is set if there is an error. ;
;===============================================;
Create_File Proc Near
Create Dx, Ax ;create
Ret
Endp ;Create_File
;===============================================;
; Get_Byte ;
; Read another byte from a file. The input is ;
; buffered. The following registers must be ;
; set: DX data segment, SI pointer, DI end of ;
; bytes, BX file handle, and CX size of buffer. ;
; Carry set if end of file and no byte ;
; returned. SI an DI are updated and AL ;
; returns the byte. ;
;===============================================;
Get_Byte Proc Near
Cmp Si, Di ;check if buffer empty
Je Gbread ;jump if so
;----- get next byte
Push Ds
Mov Ds, Dx
Lodsb ;load next byte
Pop Ds
Clc ;clear carry, byte returned
Ret
;----- read a buffer full
Gbread
Push Bx
Push Cx
Push Dx
Push Ds
Mov Ds, Dx
Sub Si, Si ;pointer to start
Read Bx, Cx, Si, Di ;read from file
Pop Ds
Pop Dx
Pop Cx
Pop Bx
Or Di, Di ;check if bytes read
Jnz Get_Byte ;jump if so, try loading again
;----- done with file
Gbempt
Stc ;set carry, finished
Ret
Endp ;Get_Byte
;===============================================;
; Divide_Byte ;
; Write byte in AL to either odd or even page ;
; file. ;
;===============================================;
Divide_Byte Proc Near
Mov Cx, Write_Size ;buffer size
Test Status, Even ;check if even page
Jnz Diveve ;jump if so
;----- store odd page byte
Mov Bx, Odd_Handle ;handle
Mov Dx, Odd_Seg ;segment
Mov Di, Odd_Point ;pointer
Call Put_Byte ;write
Mov Odd_Point, Di ;save pointer
Ret
;----- store even page byte
Diveve
Mov Bx, Eve_Handle ;handle
Mov Dx, Eve_Seg ;segment
Mov Di, Eve_Point ;pointer
Call Put_Byte ;write
Mov Eve_Point, Di ;save pointer
Ret
Endp ;Divide_Byte
;===============================================;
; Put_Byte ;
; Write another byte to a file. The output is ;
; buffered. The following registers must be ;
; set: DX data segment, DI pointer, BX file ;
; handle, and CX size of buffer, AL byte to ;
; write. Carry is set if error (disk full). ;
; DI is updated. ;
;===============================================;
Put_Byte Proc Near
Cmp Di, Cx ;check if buffer full
Je Pbwrit ;jump if so
;----- put next byte
Push Es
Mov Es, Dx
Stosb ;store byte
Pop Es
Clc ;clear carry, everything ok
Ret
;----- write a buffer full
Pbwrit
Push Ax
Push Bx
Push Cx
Push Dx
Call Write_Bytes ;write buffer
Sub Di, Di ;pointer to start
Pop Dx
Pop Cx
Pop Bx
Pop Ax
Cmp Si, Cx ;check if all bytes written
Je Put_Byte ;jump if so, now store byte
;----- error writing to file
Stc ;set carry, error
Ret
Endp ;put byte
;===============================================;
; Write_Bytes ;
; Write the number of bytes in CX at DX:0 to ;
; the file identified by the handle in BX. SI ;
; returns bytes written. ;
;===============================================;
Write_Bytes Proc Near
Push Ds
Mov Ds, Dx
Write Bx, Cx, 0, Si ;write to file
Pop Ds
Ret
Endp ;Write_Bytes
;===============================================;
; User_Break ;
; Intercept and process a user break. ;
;===============================================;
User_Break Proc Far
Bell ;sound speaker
Display_Line 'User break!!' ;show message
Stc ;set carry, abort
Ret ;return to system
Endp